from libsvm.python.svmutil import *
from sklearn.semi_supervised import LabelPropagation
from src.utils import *
import numpy as np

# SVM的api读取，没有维度概念（python原生集合结构），需转换为numpy，才能适用于某些算法对数据的格式要求
# 结构为list嵌套dict（特征）
def trans_features2numpy(features):
    result = []
    for single_img_features in features:
        single_img_features = list(single_img_features.values()) # 用SVM的api读取的话，内部是字典dict类型
        np_single_img_features = np.array(single_img_features)
        result.append(np_single_img_features)
    np_result = np.array(result)
    return np_result

class SVM(object):

    '''
    filename : 为txt文件
    '''
    def read_feature(self, filename):
        y, x = svm_read_problem(filename)  # 读入训练文件
        return y, x

    def train_model(self, all_y, all_x, options = '-c 32768.0 -g 0.0001 -b 0'):
        model = svm_train(all_y, all_x, options)  # 正式训练模型
        return model

    def predict(self, y, x, model, options = '-b 0'):
        labels, accuracy, values = svm_predict(y, x, model, options = options)
        return labels, accuracy, values


class LP(object):
    '''
    filename : 为txt文件
    '''
    def read_feature(self, filename):
        y, x = svm_read_problem(filename) # 这里也用SVM的数据读取api
        return y, x

    def train_model(self, y, x, max_iter, gamma, kernel='rbf'):
        LP = LabelPropagation(max_iter=max_iter, gamma=gamma, kernel=kernel)
        model = LP.fit(x, y) # 需要验证一下
        return model

    def predict(self, y, x, model):
        predicted_result = model.predict(x)
        accuracy = model.score(x, y)
        return predicted_result, accuracy
